import { Editor, ShortcutKey } from 'amis-editor';
import { Editor as CodeEditor } from 'amis';
import React, { useContext, useRef } from 'react';
import {
  Button, cssVar, udp, RadioGroup, useRefCallback, useAsyncEffect, Layout, useUpdateEffect,
} from '@cscec/udp-ui';
import { CodepenCircleOutlined, EyeOutlined, SaveOutlined } from '@ant-design/icons';
import { getAmisEnv, schemaUtil } from '@/components/editor/util';
import { useEditorPanel } from '@/components/editor/panel';
import type { IStore } from './type';

import '../style.less';
import { lowcodeWrapper, useAmisReWrite, useDndEvent } from '../common';
import { getTableFields, saveDesign } from './service';
import { createContentTpl } from './data';
import { buildRenderers } from '@/components/editor/plugin';
import { DesignContext, type IDCtx } from '@/components/editor/context';

const radioGroupOptions = [
  { value: 'list', label: '列表' },
  { value: 'edit', label: '明细' },
  { value: 'js', label: '脚本' },
];

function Header({ page }: { page: any }) {
  const { store, setStore } = useContext<IDCtx<IStore>>(DesignContext);
  const refreshKey = udp.getQueryValue('refreshKey');

  const onActiveKeyChange = (activeKey: string) => {
    activeKey !== 'js' && (page.designKey = activeKey);
    setStore({ activeKey });
  };

  const onPreview = () => {
    schemaUtil.setData({ amisPackages: store.packages, jsonSchema: { listInfo: store.listInfo, editInfo: store.editInfo } });
    const appTitle = `${udp.getQueryValue('appTitle') || '低码扩展'}-预览`;
    udp.open('/lowcode/preview', {
      outLink: !udp.isRunMaster, preview: 1, ...udp.getQueryValue(), id: '', AppTitle: appTitle,
    });
  };

  const onSave = async () => {
    const { listInfo, editInfo, jsInfo = '' } = store;
    const success = await saveDesign({
      id: page.Id,
      bizCode: page.busType,
      listUiContent: { ...listInfo, amisPackages: store.packages },
      editUiContent: { ...editInfo, amisPackages: store.packages },
      scriptContent: jsInfo,
    });
    if (success && refreshKey) {
      udp.refreshList(refreshKey, { id: page.Id, type: 'save' });
    }
  };

  return (
    <div className="Editor-header">
      <div className="Editor-title">
        <CodepenCircleOutlined style={{ color: cssVar.primaryColor, marginRight: 4, fontSize: 18 }} />
        {' '}
        界面自定义
      </div>
      <div className="Editor-view-mode-group-container">
        <RadioGroup options={radioGroupOptions} value={store.activeKey} onChange={onActiveKeyChange} optionType="button" buttonStyle="solid" />
      </div>
      <div className="Editor-header-actions">
        <ShortcutKey />
        <Button
          className="m-l"
          icon={<EyeOutlined />}
          onClick={onPreview}
        >
          预览
        </Button>
        <Button
          className="m-l"
          type="primary"
          onClick={onSave}
          icon={<SaveOutlined />}
        >
          保存
        </Button>
      </div>
    </div>
  );
}

function Design({ plugins, page }: { plugins?: any; page: any }) {
  const amisRef = useRef<Editor>(null);
  const { store, setStore } = useContext<IDCtx<IStore>>(DesignContext);

  const onChange = useRefCallback((value: any) => {
    setStore({ [`${store.activeKey}Info`]: value });
  });

  useEditorPanel('lowcode');

  useAmisReWrite(amisRef);

  useAsyncEffect(async () => {
    const content = await createContentTpl();
    await buildRenderers(content.packages, amisRef.current?.manager);
    setStore(content);
  }, []);

  const hiddenEditor = ['js'].includes(store.activeKey || '');

  const schemaValue = store[`${page.designKey}Info`];

  useUpdateEffect(() => {
    const editorStore = amisRef.current?.store;
    if (editorStore) {
      editorStore.setActiveId(''); // 先要置空一下才有效果，底层代码aciveId没有更新，导致试图面板不会刷新
      editorStore.setActiveId(editorStore.getRootId());
    }
  }, [page.designKey]);

  const dndEvents = useDndEvent(amisRef, page.designKey === 'list');

  return (
    <Layout className="Editor-Container" loading={store.loading}>
      <Header page={page} />
      <Layout.Flex className="Editor-inner">
        <Editor
          ref={amisRef}
          {...dndEvents}
          theme="antd"
          value={schemaValue}
          onChange={onChange}
          isMobile={false}
          className={udp.classNames('is-fixed', { hidden: hiddenEditor })}
          showCustomRenderersPanel
          plugins={plugins}
          amisEnv={getAmisEnv('design')}
        />
        <CodeEditor key="jsInfo" className={udp.classNames({ hidden: !hiddenEditor })} value={store.jsInfo} onChange={onChange} />
      </Layout.Flex>
    </Layout>
  );
}

export default lowcodeWrapper(Design, { tableService: getTableFields, isDesign: true, designType: 'extension' });
